package il.ac.bgu.cs.heuristics;

import il.ac.bgu.cs.heuristics.core.HeuristicImpProxy;
import il.ac.bgu.cs.heuristics.core.IHeuristicsEngine;
import il.ac.bgu.cs.heuristics.core.heuristicsEngineLightAOSearch;
import il.ac.bgu.cs.heuristics.core.caching.ICachingEngine;
import il.ac.bgu.cs.heuristics.core.caching.SimpleHashCaching;
import il.ac.bgu.cs.heuristics.graph.ActionGraph;
import il.ac.bgu.cs.heuristics.graph.GraphBuildEssentials;
import il.ac.bgu.cs.heuristics.graph.types.IState;
import il.ac.bgu.cs.heuristics.integration.BestFirstSearchAdapter;
import il.ac.bgu.cs.heuristics.integration.BreadthFirstSearchAdapter;
import il.ac.bgu.cs.heuristics.integration.HeuristicValueAdaptingComparator;
import il.ac.bgu.cs.heuristics.ui.MainWindow;
import il.ac.bgu.cs.heuristics.ui.UiUtils;
import il.ac.bgu.cs.heuristics.utils.Pair;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javaff.search.HValueComparator;

import org.apache.log4j.Logger;

public final class HeuristicsMain {

	private final static Logger	LOG	= Logger.getLogger(HeuristicsMain.class);

	private HeuristicsMain() {
	}

	public static void main(String[] args) {
		localTest();
		// run();
	}

	private static void run() {
		final MainWindow gui = new MainWindow();
		gui.setVisible(true);
	}

	private static void runOurTest(File domainFile, File problemFile,
			InputStream contradictions) throws IllegalArgumentException,
			IOException {
		final GraphBuildEssentials graphEssentials = GraphBuildEssentials
				.createInstance(domainFile, problemFile, contradictions);
		final ActionGraph g = new ActionGraph(graphEssentials);
		final IHeuristicsEngine heuristicEngine = new heuristicsEngineLightAOSearch(
				g);
		final ICachingEngine<Pair<IState>> cache = new SimpleHashCaching<Pair<IState>>();
		final IHeuristicsEngine proxy = new HeuristicImpProxy(heuristicEngine,
				cache);

		BestFirstSearchAdapter ourHeuristicSearchAdapter = new BestFirstSearchAdapter(
				new HeuristicValueAdaptingComparator(proxy, g.getGoalState(),
						graphEssentials));
		final String ourSolution = UiUtils.planToString(domainFile,
				problemFile, ourHeuristicSearchAdapter);

		LOG.debug(new StringBuilder().append("\n").append("Our:").append("\n")
				.append(ourSolution).append("\n").append(
						ourHeuristicSearchAdapter.getNodeCount()).append("\n")
				.append("Statistics: ").append(
						heuristicEngine.getStatisticString()).append(
						"\n=========================").append("\n").toString());

	}

	private static void runFFTest(File domainFile, File problemFile) {

		BestFirstSearchAdapter javaFFSearchAdapter = new BestFirstSearchAdapter(
				new HValueComparator());
		final String javaFFSolution = UiUtils.planToString(domainFile,
				problemFile, javaFFSearchAdapter);
		LOG.debug(new StringBuilder().append("\n").append("JavaFF:").append(
				"\n").append(javaFFSolution).append("\n").append(
				javaFFSearchAdapter.getNodeCount()).append("\n").append(
				"=========================").append("\n").toString());

	}

	private static void runBfsTest(File domainFile, File problemFile) {

		BreadthFirstSearchAdapter javaBFSAdapter = new BreadthFirstSearchAdapter();
		final String javaBFSAdapterString = UiUtils.planToString(domainFile,
				problemFile, javaBFSAdapter);
		LOG.debug(new StringBuilder().append("\n").append("BFS:").append("\n")
				.append(javaBFSAdapterString).append("\n").append(
						javaBFSAdapter.getNodeCount()).append("\n").append(
						"=========================").append("\n").toString());

	}

	/**
	 * 
	 */
	private static void localTest() {

		final String path = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\Depot";
		try {

			String DriverLogDomain = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\DriverLog\\driverlog.pddl";
			String DriverLogProblem = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\DriverLog\\pfile5.pddl";
			String DriverLogCF = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\DriverLog\\c.txt";

			String BlockWorldDomain = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\BlocksWorld\\blocksWorldTyped.pddl";
			String BlockWorldProblem = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\BlocksWorld\\problem1BlocksWorldTyped12.pddl";
			String BlockWorldCF = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\BlocksWorld\\c.txt";

			String HanoiDomain = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\hanoi\\honoi.pddl";
			String HanoiProblem = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\hanoi\\pfile1.pddl";
			String HanoiWorldCF = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\hanoi\\c.txt";

			String RocketsDomain = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\rockets\\rockets.pddl";
			String RocketsProblem = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\rockets\\pfile6.pddl";
			String RocketsWorldCF = "C:\\Documents and Settings\\haro\\Desktop\\outcome thesis\\rockets\\c.txt";

			File domainFile = new File(RocketsDomain);
			File problemFile = new File(RocketsProblem);
			InputStream contradictions = new FileInputStream(RocketsWorldCF);

			runOurTest(domainFile, problemFile, contradictions);
			// runFFTest(domainFile, problemFile);
			// runBfsTest(domainFile, problemFile);

		} catch (Exception e) {
			LOG.error("caught an exception", e);
		}
	}
}
